﻿#include "Connection/UDPConnection/UDPReceiver.h"
#include "Common/UdpSocketBuilder.h"


AUDPReceiver::AUDPReceiver()
{
	PrimaryActorTick.bCanEverTick = false;
	ListenSocket = NULL;
	UDPReceiver = NULL;
}

void AUDPReceiver::BeginPlay()
{
	Super::BeginPlay();
	StartUDPReceiver(FString("TestUDP"), FString("127.0.0.1"), 8889);
}

void AUDPReceiver::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);

	UDPReceiver->Stop();
	delete UDPReceiver;
	UDPReceiver = nullptr;

	// Clear all sockets!
	// makes sure repeat plays in Editor dont hold on to old sockets!
	if (ListenSocket)
	{
		ListenSocket->Close();
		ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ListenSocket);
	}
}

void AUDPReceiver::OnAfterReceiveData(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt)
{
	return;
}

bool AUDPReceiver::StartUDPReceiver(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort)
{
	ScreenMsg("RECEIVER INIT");

	FIPv4Address Addr;
	FIPv4Address::Parse(TheIP, Addr);
	FIPv4Endpoint Endpoint(Addr, ThePort);

	int32 BufferSize = 2 * 1024 * 1024;

	ListenSocket = FUdpSocketBuilder(*YourChosenSocketName).AsNonBlocking().AsReusable().BoundToEndpoint(Endpoint).WithReceiveBufferSize(BufferSize);;

	FTimespan ThreadWaitTime = FTimespan::FromMilliseconds(100);
	UDPReceiver = new FUdpSocketReceiver(ListenSocket, ThreadWaitTime, TEXT("UDP RECEIVER"));
	UDPReceiver->OnDataReceived().BindUObject(this, &AUDPReceiver::Recv);
	UDPReceiver->Start();
	return true;
}

void AUDPReceiver::Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt)
{
	ScreenMsg("Received bytes", ArrayReaderPtr->Num());

	FAnyCustomData Data;
	// Now de-serializing! See AnyCustomData.h
	*ArrayReaderPtr << Data;

	OnAfterReceiveData(ArrayReaderPtr, EndPt);
	BPEvent_DataReceived(Data);
}
